package com.ruoyi.logistics.service.impl;

import com.ruoyi.logistics.domain.DTO.QueryCondition;
import com.ruoyi.logistics.domain.DTO.QueryItem;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.util.List;

public class DynamicQueryBuilder {
    /**
     * 第一层
     *
     * @param conditions
     * @return
     */
    public static SearchSourceBuilder buildQuery(List<QueryCondition> conditions) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        for (QueryCondition condition : conditions) {
            BoolQueryBuilder nestedBoolQuery = buildNestedQuery(condition);
            if ("or".equalsIgnoreCase(condition.getCondition())) {
                boolQuery.should(nestedBoolQuery);
            } else {
                boolQuery.must(nestedBoolQuery);
            }
        }

        // 至少满足一个should条件
        boolQuery.minimumShouldMatch(1);
        searchSourceBuilder.query(boolQuery);
        return searchSourceBuilder;
    }

    private static BoolQueryBuilder buildNestedQuery(QueryCondition condition) {
        BoolQueryBuilder nestedBoolQuery = QueryBuilders.boolQuery();

        for (QueryItem item : condition.getList()) {
            QueryBuilder queryBuilder = buildQueryBuilder(item);

            if ("or".equalsIgnoreCase(item.getCondition())) {
                nestedBoolQuery.should(queryBuilder);
            } else {
                nestedBoolQuery.must(queryBuilder);
            }
        }

        return nestedBoolQuery;
    }

    private static QueryBuilder buildQueryBuilder(QueryItem item) {
        String field = item.getField();
        Object value = item.getValue();
        String dataType = item.getDataType();

        switch (item.getOper().toLowerCase()) {
            case "eq":
                return QueryBuilders.termQuery(field, value);
            case "gt":
                RangeQueryBuilder gt = QueryBuilders.rangeQuery(field).gt(value);
                if ("date".equals(dataType)) {
                    gt.format("yyyy-MM-dd HH:mm:ss");
                }
                return gt;
            case "lt":
                RangeQueryBuilder lt = QueryBuilders.rangeQuery(field).lt(value);
                if ("date".equals(dataType)) {
                    lt.format("yyyy-MM-dd HH:mm:ss");
                }
                return lt;
            case "gte":
                return QueryBuilders.rangeQuery(field).gte(value);
            case "lte":
                return QueryBuilders.rangeQuery(field).lte(value);
            case "match":
                return QueryBuilders.matchQuery(field, value);
            case "wildcard":
                return QueryBuilders.wildcardQuery(field, value.toString());
            default:
                throw new IllegalArgumentException("Unsupported operator: " + item.getOper());
        }
    }
}
